package com.winshare.saleAssistant.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.winshare.saleAssistant.domain.entity.ProductInfoDO;
import com.winshare.saleAssistant.model.*;
import com.winshare.saleAssistant.service.*;
import com.winshare.saleAssistant.util.JXZYZXUtil;
import com.winshare.saleAssistant.util.RedisUtils;
import com.winshare.saleAssistant.util.ToolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class JXZYZXServiceImpl implements JXZYZXService {

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    private ITUserService userService;

    @Autowired
    private IOrgManagementService orgManagementService;

    @Autowired
    private IOrgManagementLogService orgManagementLogService;

    @Autowired
    private ProductInfoService productService;

    @Autowired
    private IUserLoginLogService userLoginLogService;

    @Autowired
    private IUserOperationLogService userOperationLogService;

    @Autowired
    private ProductModularFunServiceImpl productModularFunService;

    @Autowired
    private ProductModularServiceImpl productModularService;

    /**
     * 查询同步模块功能数据
     */
    @Override
    public void queryModules() {
        List<ProductInfoDO> productList = productService.getProducts(null);
        for (ProductInfoDO product : productList) {
            OrgManagement orgManagement = orgManagementService.getOne(Wrappers.<OrgManagement>lambdaQuery().eq(OrgManagement::getSupplierId, product.getSupplierId()));
            if (orgManagement != null) {
                //环视的接口鉴权方式没有按照接口标准提供
                String token = product.getProductCode().equals("P00001") ? access_token(orgManagement.getPortaddr(), orgManagement.getAppId(), orgManagement.getAppSecretKey()) : "";
                getModules(orgManagement, orgManagement.getPortaddr(), product.getProductCode(), token);
                orgManagement.setAddtime(new Date());
                orgManagement.setTotal(orgManagement.getTotal() + 1);
                orgManagementService.updateById(orgManagement);
            }
        }
    }

    /**
     * 查询同步用户数据
     */
    @Override
    public void queryUser() {
        List<ProductInfoDO> productList = productService.getProducts(null);
        for (ProductInfoDO product : productList) {
            OrgManagement orgManagement = orgManagementService.getOne(Wrappers.<OrgManagement>lambdaQuery().eq(OrgManagement::getSupplierId, product.getSupplierId()));
            if (orgManagement != null) {
                //环视的接口鉴权方式没有按照接口标准提供
                String token = product.getProductCode().equals("P00001") ? access_token(orgManagement.getPortaddr(), orgManagement.getAppId(), orgManagement.getAppSecretKey()) : "";
                getaccounts(orgManagement, orgManagement.getPortaddr(), product.getProductCode(), token, "0", Integer.parseInt(product.getId() + ""));
                orgManagement.setAddtime(new Date());
                orgManagement.setTotal(orgManagement.getTotal() + 1);
                orgManagementService.updateById(orgManagement);
            }
        }
    }

    /**
     * 查询同步用户登录记录数据
     *
     * @param beginDate
     * @param endDate
     */
    @Override
    public void queryLoginLogs(String beginDate, String endDate) {
        List<ProductInfoDO> productList = productService.getProducts(null);
        for (ProductInfoDO product : productList) {
            OrgManagement orgManagement = orgManagementService.getOne(Wrappers.<OrgManagement>lambdaQuery().eq(OrgManagement::getSupplierId, product.getSupplierId()));
            if (orgManagement != null) {
                //环视的接口鉴权方式没有按照接口标准提供
                String token = product.getProductCode().equals("P00001") ? access_token(orgManagement.getPortaddr(), orgManagement.getAppId(), orgManagement.getAppSecretKey()) : "";
                getLoginLogs(orgManagement, orgManagement.getPortaddr(), product.getProductCode(), token, "0", beginDate, endDate, product.getProductName(), Integer.parseInt(product.getId() + ""));
                orgManagement.setAddtime(new Date());
                orgManagement.setTotal(orgManagement.getTotal() + 1);
                orgManagementService.updateById(orgManagement);
            }
        }
    }

    /**
     * 获取用户操作日志
     *
     * @param beginDate
     * @param endDate
     */
    @Override
    public void queryUseOperationLogs(String beginDate, String endDate) {
        List<ProductInfoDO> productList = productService.getProducts(null);
        for (ProductInfoDO product : productList) {
            OrgManagement orgManagement = orgManagementService.getOne(Wrappers.<OrgManagement>lambdaQuery().eq(OrgManagement::getSupplierId, product.getSupplierId()));
            if (orgManagement != null) {
                //环视的接口鉴权方式没有按照接口标准提供
                String token = product.getProductCode().equals("P00001") ? access_token(orgManagement.getPortaddr(), orgManagement.getAppId(), orgManagement.getAppSecretKey()) : "";
                getUseOperationLogs(orgManagement, orgManagement.getPortaddr(), product.getProductCode(), token, "0", beginDate, endDate, Integer.parseInt(product.getId() + ""));
                orgManagement.setAddtime(new Date());
                orgManagement.setTotal(orgManagement.getTotal() + 1);
                orgManagementService.updateById(orgManagement);
            }
        }
    }

    /**
     * 获得某个产品的全部模块清单
     *
     * @param url
     * @param produceCode  产品编码
     * @param access_token 授权令牌
     * @return
     */
    private void getModules(OrgManagement orgManagement, String url, String produceCode, String access_token) {
        JSONObject jsonObject = JXZYZXUtil.getmodules(url, produceCode, access_token, orgManagement.getAppSecretKey());
        Integer state = 2;
        if (jsonObject.getInteger("code") == 0) {
            state = 1;
            JSONArray jsonArray = null;
            if (produceCode.equals("P00001")) {
                jsonArray = jsonObject.getJSONArray("data");
            } else {
                JSONObject pageJson = jsonObject.getJSONObject("data");
                jsonArray = pageJson.getJSONArray("list");
            }
            for (int i = 0; i < jsonArray.size(); i++) {
                ProductModular productModular = productModularService.getOne(Wrappers.<ProductModular>lambdaQuery().eq(ProductModular::getProductCode, produceCode).eq(ProductModular::getModularCode, jsonArray.getJSONObject(i).getString("modelCode")));
                if (productModular == null) {
                    productModular = new ProductModular();
                }
                productModular.setProductCode(produceCode);
                //教育资源中心接口字段未按照文档提供
                if (produceCode.equals("P00001")) {
                    productModular.setModularName(jsonArray.getJSONObject(i).getString("modelName"));
                    productModular.setModularCode(jsonArray.getJSONObject(i).getString("modelCode"));
                    productModular.setModularRemark(jsonArray.getJSONObject(i).getString("modelRemark"));
                } else {
                    productModular.setModularName(jsonArray.getJSONObject(i).getString("moduleName"));
                    productModular.setModularCode(jsonArray.getJSONObject(i).getString("moduleCode"));
                    productModular.setModularRemark(jsonArray.getJSONObject(i).getString("moduleRemark"));
                }
                productModularService.saveOrUpdate(productModular);
                //获取模块功能数据
                getFuncs(orgManagement, url, produceCode, access_token, productModular.getModularCode());
            }
        }
        Map<String, String> param = new HashMap<>();
        param.put("produceCode", produceCode);
        param.put("access_token", access_token);
        param.put("method", "getmodules");
        addLog(orgManagement, JSONObject.toJSONString(param), jsonObject.toJSONString(), state, url + "?method=getmodules");
    }

    /**
     * 获得某个产品的某块模块下的全部功能清单
     *
     * @param url
     * @param produceCode  产品编码
     * @param modelCode    模块编码
     * @param access_token 授权令牌
     * @return
     */
    private void getFuncs(OrgManagement orgManagement, String url, String produceCode, String access_token, String modelCode) {
        JSONObject jsonObject = JXZYZXUtil.getfuncs(url, produceCode, access_token, modelCode, orgManagement.getAppSecretKey());
        Integer state = 2;
        if (jsonObject.getInteger("code") == 0) {
            state = 1;
            JSONArray jsonArray = null;
            if (produceCode.equals("P00001")) {
                jsonArray = jsonObject.getJSONArray("data");
            } else {
                JSONObject pageJson = jsonObject.getJSONObject("data");
                jsonArray = pageJson.getJSONArray("list");
            }
            for (int i = 0; i < jsonArray.size(); i++) {
                ProductModularFun productModularFun = productModularFunService.getOne(Wrappers.<ProductModularFun>lambdaQuery().eq(ProductModularFun::getProductCode, produceCode).eq(ProductModularFun::getModularCode, jsonArray.getJSONObject(i).getString("modelCode")).eq(ProductModularFun::getFunCode, jsonArray.getJSONObject(i).getString("funcCode")));
                if (productModularFun == null) {
                    productModularFun = new ProductModularFun();
                }
                productModularFun.setProductCode(produceCode);
                productModularFun.setModularCode(modelCode);
                productModularFun.setFunName(jsonArray.getJSONObject(i).getString("funcName"));
                productModularFun.setFunCode(jsonArray.getJSONObject(i).getString("funcCode"));
                productModularFun.setFunRemark(jsonArray.getJSONObject(i).getString("funcRemark"));
                productModularFunService.saveOrUpdate(productModularFun);
            }
        }
        Map<String, String> param = new HashMap<>();
        param.put("produceCode", produceCode);
        param.put("modelCode", modelCode);
        param.put("access_token", access_token);
        param.put("method", "getfuncs");
        addLog(orgManagement, JSONObject.toJSONString(param), jsonObject.toJSONString(), state, url + "?method=getfuncs");
    }

    private void getUseOperationLogs(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, String beginDate, String endDate, Integer produceId) {
        getUseOperationLogs(orgManagement, url, produceCode, access_token, timestamp, beginDate, endDate, 1, produceId);
    }

    /**
     * 循环加载操作日志
     *
     * @param url
     * @param produceCode  产品编号
     * @param access_token token
     * @param timestamp    时间戳
     * @param beginDate    开始时间 yyyy-MM-dd HH:mm:ss
     * @param endDate      结束时间 yyyy-MM-dd HH:mm:ss
     * @param pageNo       页码
     * @return
     */
    private Boolean getUseOperationLogs(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, String beginDate, String endDate, Integer pageNo, Integer produceId) {
        try {
            SimpleDateFormat days = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            JSONObject jsonObject = JXZYZXUtil.getuselogs(url, produceCode, access_token, timestamp, beginDate, endDate, pageNo, 1000, orgManagement.getAppSecretKey());
            Integer state = 2;
            if (jsonObject.getInteger("code") == 0) {
                state = 1;
                JSONObject pageJson = jsonObject.getJSONObject("data");
                JSONArray jsonArray = pageJson.getJSONArray("list");
                for (int i = 0; i < jsonArray.size(); i++) {
                    UserOperationLog userOperationLog = new UserOperationLog();
                    userOperationLog.setUserId(jsonArray.getJSONObject(i).getString("userId"));
                    userOperationLog.setProductCode(produceCode);
                    userOperationLog.setProductId(produceId);
                    userOperationLog.setVersionCode(jsonArray.getJSONObject(i).getString("version"));
                    userOperationLog.setModularCode(produceCode.equals("P00001") ? jsonArray.getJSONObject(i).getString("modelCode") : jsonArray.getJSONObject(i).getString("moduleCode"));
                    userOperationLog.setFunctionCode(jsonArray.getJSONObject(i).getString("funcCode"));
                    userOperationLog.setUseTime(days.parse(jsonArray.getJSONObject(i).getString("useTime")));
                    userOperationLog.setUseDuration(jsonArray.getJSONObject(i).getString("useDuration"));
                    userOperationLogService.save(userOperationLog);
                }
                int nowPageNo = pageJson.getInteger("pageNo");
                int totalPage = pageJson.getInteger("totalPage");
                Map<String, String> param = new HashMap<>();
                SetRequestParam(param, produceCode, access_token, timestamp, pageNo);
                param.put("method", "getuselogs");
                if (ToolUtil.isNotEmpty(beginDate)) param.put("beginDate", beginDate);
                if (ToolUtil.isNotEmpty(beginDate)) param.put("endDate", endDate);
                addLog(orgManagement, JSONObject.toJSONString(param), "返回数据条数:" + jsonArray.size(), state, url + "?method=getuselogs");
                if (nowPageNo < totalPage) {
                    getUseOperationLogs(orgManagement, url, produceCode, access_token, timestamp, beginDate, endDate, pageNo + 1, produceId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


    /**
     * 加载登录日志
     *
     * @param orgManagement
     * @param url
     * @param produceCode
     * @param access_token
     * @param timestamp
     * @param beginDate
     * @param endDate
     * @param produceName
     * @param produceId
     */
    private void getLoginLogs(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, String beginDate, String endDate, String produceName, Integer produceId) {
        getLoginLogs(orgManagement, url, produceCode, access_token, timestamp, beginDate, endDate, 1, produceName, produceId);
    }

    /**
     * 循环加载登录日志
     *
     * @param url
     * @param produceCode  产品编号
     * @param access_token token
     * @param timestamp    当前时间戳
     * @param beginDate    开始时间 yyyy-MM-dd HH:mm:ss
     * @param endDate      结束时间 yyyy-MM-dd HH:mm:ss
     * @param pageNo       页码
     * @return
     */
    private Boolean getLoginLogs(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, String beginDate, String endDate, Integer pageNo, String produceName, Integer produceId) {
        try {
            SimpleDateFormat days = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            JSONObject jsonObject = JXZYZXUtil.getloginlogs(url, produceCode, access_token, timestamp, beginDate, endDate, pageNo, 1000, orgManagement.getAppSecretKey());
            Integer state = 2;
            if (jsonObject.getInteger("code") == 0) {
                state = 1;
                JSONObject pageJson = jsonObject.getJSONObject("data");
                JSONArray jsonArray = pageJson.getJSONArray("list");
                for (int i = 0; i < jsonArray.size(); i++) {
                    UserLoginLog userLogging = new UserLoginLog();
                    userLogging.setUserId(jsonArray.getJSONObject(i).getString("userId"));
                    userLogging.setProductCode(produceCode);
                    userLogging.setProductName(produceName);
                    userLogging.setProductId(produceId);
                    userLogging.setVersionCode(jsonArray.getJSONObject(i).getString("version"));
                    userLogging.setRegisterTime(days.parse(jsonArray.getJSONObject(i).getString("recordTime")));
                    userLogging.setDeviceType(jsonArray.getJSONObject(i).getString("deviceType"));
                    userLogging.setProvinceName(jsonArray.getJSONObject(i).getString("province"));
                    userLogging.setCityName(jsonArray.getJSONObject(i).getString("city"));
                    userLogging.setAreaName(jsonArray.getJSONObject(i).getString("county"));
                    userLogging.setUnitType(produceCode.equals("P00001")?jsonArray.getJSONObject(i).getString("deviceModel"):jsonArray.getJSONObject(i).getString("deviceModule"));
                    userLoginLogService.save(userLogging);
                }
                int nowPageNo = pageJson.getInteger("pageNo");
                int totalPage = pageJson.getInteger("totalPage");
                Map<String, String> param = new HashMap<>();
                SetRequestParam(param, produceCode, access_token, timestamp, pageNo);
                param.put("method", "getloginlogs");
                if (ToolUtil.isNotEmpty(beginDate)) param.put("beginDate", beginDate);
                if (ToolUtil.isNotEmpty(beginDate)) param.put("endDate", endDate);
                addLog(orgManagement, JSONObject.toJSONString(param), "返回数据条数:" + jsonArray.size(), state, url + "?method=getloginlogs");
                if (nowPageNo < totalPage) {
                    getLoginLogs(orgManagement, url, produceCode, access_token, timestamp, beginDate, endDate, pageNo + 1, produceName, produceId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 设置接口请求参数
     *
     * @param param
     * @param produceCode
     * @param access_token
     * @param timestamp
     * @param pageNo
     */
    private void SetRequestParam(Map<String, String> param, String produceCode, String access_token, String timestamp, Integer pageNo) {
        param.put("produceCode", produceCode);
        param.put("timestamp", timestamp);
        param.put("access_token", access_token);
        param.put("pageNo", pageNo + "");
        param.put("pageSize", 1000 + "");
    }

    /**
     * 获得某个产品的帐号信息
     *
     * @param url
     * @param produceCode  产品编码
     * @param timestamp    时间戳
     * @param access_token 授权令牌
     * @return
     */
    private void getaccounts(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, Integer productId) {
        getAccounts(orgManagement, url, produceCode, access_token, timestamp, 1, productId);
    }

    /**
     * 循环加载用户数据
     *
     * @param url
     * @param produceCode
     * @param access_token
     * @param timestamp
     * @param pageNo
     * @return
     */
    private Boolean getAccounts(OrgManagement orgManagement, String url, String produceCode, String access_token, String timestamp, Integer pageNo, Integer productId) {
        try {
            SimpleDateFormat days = new SimpleDateFormat("yyyy-MM-dd");
            JSONObject jsonObject = JXZYZXUtil.getaccounts(url, produceCode, access_token, timestamp, pageNo, 1000, orgManagement.getAppSecretKey());
            Integer state = 2;
            if (jsonObject.getInteger("code") == 0) {
                state = 1;
                JSONObject pageJson = jsonObject.getJSONObject("data");
                JSONArray jsonArray = pageJson.getJSONArray("list");
                for (int i = 0; i < jsonArray.size(); i++) {
                    TUser user = userService.getOne(new QueryWrapper<TUser>().eq("user_id", jsonArray.getJSONObject(i).getString("userId")).eq("product_code", produceCode));
                    if (user == null) {
                        user = new TUser();
                    }
                    user.setUserId(jsonArray.getJSONObject(i).getString("userId"));
                    user.setUserName(jsonArray.getJSONObject(i).getString("userName"));
                    user.setSex(jsonArray.getJSONObject(i).getString("userSex"));
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("userBirthYear"))) {
                        user.setBirthYear(jsonArray.getJSONObject(i).getString("userBirthYear"));
                    }
                    user.setPhone(jsonArray.getJSONObject(i).getString("userPhone"));
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("schoolName"))) {
                        user.setSchoolName(jsonArray.getJSONObject(i).getString("schoolName"));
                    }
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("schoolCode"))) {
                        user.setSchoolCode(jsonArray.getJSONObject(i).getString("schoolCode"));
                    }
                    user.setType(jsonArray.getJSONObject(i).getString("userType"));
                    user.setLearningSection(jsonArray.getJSONObject(i).getString("userPhase"));
                    user.setSubject(jsonArray.getJSONObject(i).getString("userSubject"));
                    user.setProductCode(produceCode);
                    user.setProductId(productId);
                    user.setVersionCode(jsonArray.getJSONObject(i).getString("version"));
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("buyDate"))) {
                        user.setBuyTime(days.parse(jsonArray.getJSONObject(i).getString("buyDate")));
                    }
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("activateDate"))) {
                        user.setActivationTime(days.parse(jsonArray.getJSONObject(i).getString("activateDate")));
                    }
                    if (ToolUtil.isNotEmpty(jsonArray.getJSONObject(i).getString("expiredDate"))) {
                        user.setBeOverdueTime(days.parse(jsonArray.getJSONObject(i).getString("expiredDate")));
                    }
                    user.setCreateTime(new Date());
                    userService.saveOrUpdate(user);
                }
                int nowPageNo = pageJson.getInteger("pageNo");
                int totalPage = pageJson.getInteger("totalPage");
                Map<String, String> param = new HashMap<>();
                SetRequestParam(param, produceCode, access_token, timestamp, pageNo);
                param.put("method", "getaccounts");
                addLog(orgManagement, JSONObject.toJSONString(param), "返回数据条数:" + jsonArray.size(), state, url + "?method=getaccounts");
                if (nowPageNo < totalPage) {
                    getAccounts(orgManagement, url, produceCode, access_token, timestamp, pageNo + 1, productId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取token
     *
     * @param url       请求路径
     * @param appID     应用APPid
     * @param appSecret 秘钥
     */
    public String access_token(String url, String appID, String appSecret) {
//        String token = redisUtils.get(appID);
//        if (ToolUtil.isEmpty(token)) {
//            JSONObject jsonObject = JXZYZXUtil.access_token(url, appID, appSecret);
//            if (jsonObject.getString("app_op_msg").equals("success")) {
//                redisUtils.set(appID, jsonObject.getJSONObject("app_op_content").getString("access_token"), 2 * 60 * 60);
//                token = jsonObject.getJSONObject("app_op_content").getString("access_token");
//            }
//        }
        JSONObject jsonObject = JXZYZXUtil.access_token(url, appID, appSecret);
        String token = jsonObject.getJSONObject("app_op_content").getString("access_token");
        return token;
    }

    /**
     * 添加接口调用日志
     *
     * @param orgManagement 接口信息
     * @param paramText     请求参数
     * @param resultText    返回参数
     * @param state         状态 1 正常 2异常
     * @param url           接口地址
     */
    private void addLog(OrgManagement orgManagement, String paramText, String resultText, Integer state, String url) {
        OrgManagementLog orgManagementLog = new OrgManagementLog();
        orgManagementLog.setAddtime(new Date());
        orgManagementLog.setOid(orgManagement.getId());
        orgManagementLog.setSupplier(orgManagement.getSupplier());
        orgManagementLog.setPortaddr(url);
        orgManagementLog.setState(state);
        orgManagementLog.setCycle(orgManagement.getCycle());
        orgManagementLog.setResultText(resultText);
        orgManagementLog.setParamText(paramText);
        orgManagementLogService.save(orgManagementLog);
    }
}
